const {ccclass, property} = cc._decorator;

@ccclass
export default class JellyTween extends cc.Component {

    @property
    frequency = 4;
  
    @property
    decay = 2;
    
    @property
    pressScale = 0.2;
    
    @property
    totalTime = 1;
    
    @property
    interval = 1;
    
    @property
    playOnLoad = false;
    
    originalScale = 1;
    tween = null;

    onLoad() { }

    start() {
        this.originalScale = this.node.scale;
        if (this.playOnLoad) {
            this.play();
        }
    }

    play(e?) {
        const repeatCount = e != null && e > 0 ? e : 1000000000;
        const pressTime = 0.2 * this.totalTime;
        const releaseTime = 0.15 * this.totalTime;
        const pushTime = 0.65 * this.totalTime;
        const pushFrequency = this.pressScale / releaseTime;

        this.tween = cc.tween(this.node)
            .repeat(repeatCount,
                cc.tween()
                    .to(pressTime, {scaleX: this.originalScale + this.pressScale, scaleY: this.originalScale - this.pressScale}, {easing: 'sineOut'})
                    .to(releaseTime, {scaleX: this.originalScale, scaleY: this.originalScale})
                    .to(pushTime, {
                        scaleX: {
                            value: this.originalScale,
                            progress: (startValue, endValue, current, ratio) => {
                                return endValue - this.getDifference(pushFrequency, ratio);
                            }
                        },
                        scaleY: {
                            value: this.originalScale,
                            progress: (startValue, endValue, current, ratio) => {
                                return endValue + this.getDifference(pushFrequency, ratio);
                            }
                        },
                    })
                    .delay(this.interval)
            )
            .start();
    }

    stop() {
        if (this.tween) {
            this.tween.stop();
        }
        this.node.setScale(this.originalScale);
    }

    getDifference(frequency, t) {
        const angle = frequency * Math.PI * 2;
        return frequency * (Math.sin(t * angle) / Math.exp(this.decay * t) / angle);
    }

}
